import React from 'react';
import PropTypes from 'prop-types';
import { Button, Icon, Input, Table, Tooltip, Modal, Form, Popconfirm, message } from 'antd';
import cn from 'classnames';
import _ from 'lodash';
import './index.less';

class ConfigPageTemplate extends React.Component {
  static propTypes = {
    className: PropTypes.string,
    name: PropTypes.string,
    title: PropTypes.string,
    titleInfo: PropTypes.string,
    addBtnDesc: PropTypes.string,
    searchPlaceholder: PropTypes.string,
    showTotal: PropTypes.func,
    contentColumns: PropTypes.array,
    loadData: PropTypes.func,
    saveData: PropTypes.func,
    deleteData: PropTypes.func,
    addModalTitle: PropTypes.string,
    editModalTitle: PropTypes.string,
    deleteDesc: PropTypes.string,
    formItems: PropTypes.array,
    form: PropTypes.object,
    formProps: PropTypes.object,
    disableOptRow: PropTypes.func
  };
  constructor(props) {
    super(props);
    this.state = {
      list: [],
      count: 0,
      current: 1,
      pageSize: 10,
      search: '',
      modalVisible: false,
      currentItem: null,
      saving: false,
      loading: false
    };
  }
  componentDidMount() {
    this.loadData();
  }
  loadData = () => {
    const { current, pageSize, search } = this.state;
    this.setState({ loading: true });
    this.props
      .loadData({ current, pageSize, search })
      .then(({ list = [], count = 0 }) => {
        this.setState({
          list,
          count
        });
      })
      .finally(() => {
        this.setState({ loading: false });
      });
  };
  cancelSave = () => {
    this.setState(
      {
        modalVisible: false,
        currentItem: null,
        saving: false
      },
      this.props.form.resetFields
    );
  };
  saveData = () => {
    const {
      form,
      name,
      addModalTitle = `添加${name}`,
      editModalTitle = `编辑${name}`,
      saveData
    } = this.props;
    form.validateFields((err, data) => {
      if (err) {
        return;
      }
      const actionDesc = data._id ? editModalTitle : addModalTitle;
      this.setState({ saving: true });
      Promise.resolve(saveData(data))
        .then(() => {
          message.success(`${actionDesc}成功`);
          this.setState(
            {
              modalVisible: false,
              currentItem: null
            },
            () => {
              this.loadData();
              form.resetFields();
            }
          );
        })
        .catch(err => {
          if (_.includes(_.get(err, 'message', ''), 'E11000 duplicate key error')) {
            message.error(`${actionDesc}失败：存在相同的${name}`);
          } else {
            message.error(`${actionDesc}失败`);
          }
        })
        .finally(() => {
          this.setState({ saving: false });
        });
    });
  };
  deleteData = data => {
    const { name, deleteDesc = `删除${name}` } = this.props;
    Promise.resolve(this.props.deleteData(data))
      .then(() => {
        message.success(`${deleteDesc}成功`);
        this.loadData();
      })
      .catch(() => {
        message.error(`${deleteDesc}失败`);
      });
  };
  render() {
    const {
      name,
      className,
      title = `${name}管理`,
      titleInfo,
      addBtnDesc = `添加${name}`,
      searchPlaceholder,
      showTotal = total => `共有"${total}"个${name}`,
      contentColumns,
      addModalTitle = `添加${name}`,
      editModalTitle = `编辑${name}`,
      formItems,
      form,
      formProps = {},
      disableOptRow
    } = this.props;
    const { getFieldDecorator } = form;

    const {
      list,
      count,
      current,
      pageSize,
      currentItem,
      modalVisible,
      saving,
      loading
    } = this.state;

    const optColumn = {
      title: '操作',
      key: 'opts',
      render: row => {
        const disabled = typeof disableOptRow === 'function' && disableOptRow(row);
        if (disabled) {
          return (
            <div className="opt-cell disabled">
              <Tooltip title={`该${name}为系统内置${name}，不能进行编辑`}>
                <span className="edit">编辑</span>
              </Tooltip>
              <Tooltip title={`该${name}为系统内置${name}，不能进行删除`}>
                <span className="delete">删除</span>
              </Tooltip>
            </div>
          );
        } else {
          return (
            <div className="opt-cell">
              <a
                className="edit"
                onClick={() => {
                  this.props.form.setFieldsValue(row, () =>
                    this.setState({ modalVisible: true, currentItem: row })
                  );
                }}
              >
                编辑
              </a>
              <Popconfirm
                title={`确定要删除该${name}吗`}
                className="delete"
                onConfirm={() => this.deleteData(row)}
              >
                删除
              </Popconfirm>
            </div>
          );
        }
      }
    };

    return (
      <div className={cn('config-page-template', className)}>
        <div className="title">
          {title}
          {titleInfo && (
            <Tooltip
              className="info"
              placement="right"
              overlayClassName={cn('config-page-template-title-info', `${className}-title-info`)}
              title={titleInfo}
            >
              <Icon type="exclamation-circle" />
            </Tooltip>
          )}
        </div>
        <div className="opts">
          <Button
            className="add-btn"
            type="primary"
            onClick={() => this.setState({ currentItem: null, modalVisible: true })}
          >
            <Icon type="plus-circle" />
            {addBtnDesc}
          </Button>
          <Input.Search
            className="search"
            enterButton
            placeholder={searchPlaceholder}
            onSearch={search => this.setState({ current: 1, search }, this.loadData)}
          />
        </div>
        {showTotal && <div className="total-info">{showTotal(count)}</div>}
        <Table
          className="data"
          columns={contentColumns.concat(optColumn)}
          dataSource={list}
          loading={loading}
          pagination={{ total: count, current, pageSize, showSizeChanger: true }}
        />
        <Modal
          maskClosable={false}
          className={cn(
            'config-page-template-modal',
            `${className}-modal`,
            'no-header-bottom-lines',
            'bottom-center',
            'padding-24'
          )}
          visible={modalVisible}
          title={currentItem ? editModalTitle : addModalTitle}
          onOk={this.saveData}
          onCancel={this.cancelSave}
          confirmLoading={saving}
        >
          <Form
            colon={false}
            labelAlign="left"
            labelCol={{ span: 4 }}
            wrapperCol={{ span: 20 }}
            {...formProps}
          >
            <Form.Item hidden>{getFieldDecorator('_id')(<Input />)}</Form.Item>
            {formItems.map(option => {
              return (
                <Form.Item required={option.required} label={option.label} key={option.key}>
                  {getFieldDecorator(option.key, option.options)(option.element)}
                </Form.Item>
              );
            })}
          </Form>
        </Modal>
      </div>
    );
  }
}

export default Form.create()(ConfigPageTemplate);
